R Markdown

This is an R Markdown document. Markdown is a simple formatting syntax for authoring HTML, PDF, and MS Word documents. For more details on using R Markdown see http://rmarkdown.rstudio.com.

When you click the Knit button a document will be generated that includes both content as well as the output of any embedded R code chunks within the document. You can embed an R code chunk like this:

# Load necessary libraries
library(ggplot2)
## Warning: package 'ggplot2' was built under R version 4.3.3
library(gganimate)
## Warning: package 'gganimate' was built under R version 4.3.3
library(dplyr)
## 
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
# Set constants
amplitude <- 10
amplitude_1 <- 5
amplitude_2 <- 2
duration <- 2
freq_1 <- 4
freq_2 <- 100
sample_rate <- 400
lowFreq <- 20
highFreq <- 41
time_gl <- seq(0, duration, 1/sample_rate)

# Function to generate signal, FFT, and inverse FFT
generate_signal_fft <- function(frequency) {
  primary_signal <- amplitude * sin(pi * frequency * time_gl)
  signal_1 <- amplitude_1 * sin(pi * freq_1 * time_gl)
  signal_2 <- amplitude_2 * sin(pi * freq_2 * time_gl)
  
  combined_signal <- primary_signal + signal_1 + signal_2
  
  # Perform FFT
  signal_yfft <- fft(combined_signal)
  pow_spectrum <- abs(signal_yfft)
  
  n <- length(signal_yfft)
  # Remove stationary frequencies
  signal_yfft[c(freq_1, freq_2, n - freq_1 + 1, n - freq_2 + 1)] <- 0
  
  # Perform inverse FFT
  signal_yInvfft <- Re(fft(signal_yfft, inverse = TRUE)) / n
  list(original = combined_signal, 
       power_spectrum = pow_spectrum, 
       filtered = signal_yInvfft)
}

# Create empty data frames for animation
original_data <- data.frame()
power_data <- data.frame()
inverse_data <- data.frame()

# Generate data for each frequency step
for (freqID in seq(lowFreq, highFreq)) {
  results <- generate_signal_fft(freqID)
  
  # Accumulate data for animation
  original_data <- rbind(original_data, 
                          data.frame(time = time_gl, 
                                     signal = results$original, 
                                     frequency = freqID))

  power_data <- rbind(power_data, 
                       data.frame(time = seq(0, 200, length.out = length(results$power_spectrum)), 
                                  signal = results$power_spectrum[1:length(results$power_spectrum)], 
                                  frequency = freqID))

  inverse_data <- rbind(inverse_data, 
                         data.frame(time = time_gl, 
                                    signal = results$filtered, 
                                    frequency = freqID))
}
# Create the animated plots
# No need to wrap in ggplot, just create frames for the animation
original_animation <- ggplot(original_data, aes(x = time, y = signal)) +
  geom_line(color = "red") +
  labs(title = "Original Combined Signal: {frame_time}", x = "Time (s)", y = "Amplitude") +
  theme_minimal() +
  ylim(-20, 20) +
  transition_time(frequency)
original_animation

power_animation <- ggplot(power_data, aes(x = time, y = signal)) +
  geom_line(color = "blue") +
  labs(title = "Power Spectrum: {frame_time}", x = "Frequency Bin", y = "Magnitude") +
  theme_minimal() +
  ylim(0, max(power_data$signal)) +
  transition_time(frequency)
power_animation

inverse_animation <- ggplot(inverse_data, aes(x = time, y = signal)) +
  geom_line(color = "orange") +
  labs(title = "Inverse FFT Signal: {frame_time}", x = "Time (s)", y = "Amplitude") +
  theme_minimal() +
  ylim(-20, 20) +
  transition_time(frequency)
inverse_animation